
//
// 120316 - AH - (Aura) Created.
// 120317 - AH - (Huset *) print(PrintWriter, Object).
// 120727 - AH - (Midtun) Object to serialize is now SoekratResponse. 
//

package org.soekrat.server.serialization;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import org.soekrat.server.serialization.json.JsonTextSerializator;
import org.soekrat.server.servlets.SoekratResponse;

/**
 * <p>
 *   Base class for objects that serialize to text representation. 
 * </p>
 * <p>
 *   Use 
 *   {@link #getTextSerializator(String)} to get
 *   {@link TextSerializator} for a given MIME type.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public abstract class TextSerializator 
{
  private final String m_mime;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param mime MIME type of format {@code this} produce.
   */
  protected TextSerializator(String mime)
  {
    if (mime==null)
    {
      throw new NullPointerException("mime");
    }
    
    m_mime=mime;
  }
  
  /**
   * <p>
   *   Gets MIME type of format {@code this} produce.
   * </p>
   * @return MIME type.
   */
  public final String getMime(){ return m_mime; }
  
  /**
   * <p>
   *   Prints serialized.
   * </p>
   * @param pw Stream to print to.
   * @param o  Object to print serialized representation to.
   * @throws IOException If fails.
   */
  public final void print(PrintWriter pw, SoekratResponse o) throws IOException
  {
    if (pw==null)
    {
      throw new NullPointerException("pw");
    }
    if (o==null)
    {
      throw new NullPointerException("o");
    }
    
    pw.println(serialize(o));
    pw.flush();
  }
  
  /**
   * <p>
   *   Serializes.
   * </p>
   * @param o {@code Object} to serialize.
   * @return {@code String} representation of {@code o}.
   * @throws IOException If fails.
   */
  public abstract String serialize(SoekratResponse o) throws IOException;
  
  private static final Map<String, TextSerializator> c_serializators=
    new HashMap<String, TextSerializator>();
  
  private static String c_defaultMIME="application/json";
  
  /**
   * <p>
   *   Sets default MIME.
   * </p>
   * @param mime MIME to set.
   * @throws IllegalArgumentException If there is no known
   *         {@link TextSerializator} for MIME type {@code mime}.
   */
  public static void setDefaultMIME(String mime)
  {
    if (mime==null)
    {
      throw new NullPointerException("mime");
    }
    
    if (!c_serializators.containsKey(mime))
    {
      throw new IllegalArgumentException("mime : "+mime+" uknown");
    }
    
    c_defaultMIME=mime;
  }
  
  /**
   * <p>
   *   Gets default MIME type.
   * </p>
   * @return Default.
   */
  public static String getDefaultMIME(){ return c_defaultMIME; }
  
  /**
   * <p>
   *   Adds 
   *   {@code TextSerializator}. 
   * </p>
   * @param ts {@code TextSerializator} to add.
   */
  private static void addTextSerializator(TextSerializator ts)
  {
    if (ts==null)
    {
      throw new NullPointerException("ts");
    }
    
    c_serializators.put(ts.getMime(), ts);
  }
  
  static 
  {
    addTextSerializator(new JsonTextSerializator());
  }
  
  /**
   * <p>
   *   Gets the default
   *   {@code TextSerializator}.
   * </p>
   * @return {@code TextSerializator} that is the default.
   */
  public static TextSerializator getTextSerializator()
  {
    return c_serializators.get(c_defaultMIME);
  }
  
  /**
   * <p>
   *   Gets
   *   {@link TextSerializator} for given MIME type.
   * </p>
   * @param mime MIME type, if {@code null} returns the 
   *             {@link TextSerializator} for the 
   *             {@link #getDefaultMIME() default MIME type}.
   * @return {@link TextSerializator} or {@code null} if not found.
   */
  public static TextSerializator getTextSerializator(String mime)
  {
    mime=(mime==null) ? c_defaultMIME : mime;
    
    return c_serializators.get(mime);
  }
  
}
